package com.maoslv.security;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.maoslv.pojo.User;
import com.maoslv.service.user.UserService;
import com.maoslv.utils.JWTUtil;
import com.maoslv.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class JwtFilter extends BasicAuthenticationFilter {

    @Autowired
    UserService userService;

    @Autowired
    UserDetailServiceImpl userDetailService;

    @Autowired
    RedisUtil redisUtil;

    public JwtFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String jwt = request.getHeader("Authorization");
        if (jwt == null || jwt.equals("") || jwt.equals("null")) {
            chain.doFilter(request,response);
            return;
        }
        DecodedJWT verify = null;
        try {
            //校验token 如果合法且没过期就不会报异常
            verify = JWTUtil.verify(jwt);
        } catch (Exception e) {
            throw e;
        }
        String username = verify.getClaim("username").asString();
        if (redisUtil.get(username + "-jwt") == null) {
            request.setAttribute("exception", "用户信息已过期");
            throw new RuntimeException("用户信息已过期");
        }
        User user = userService.getByUsername(username);
        //获取用户权限信息
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username,null,userDetailService.getUserAuthority(user.getId()));
        //认证
        SecurityContextHolder.getContext().setAuthentication(token);
        chain.doFilter(request,response);
    }
}
